﻿using ConfigInfoWebPlatform.API.DBCommon;
using ConfigInfoWebPlatform.API.ViewModel;
using ConfigInfoWebPlatform.Model;
using ConfigInfoWebPlatform.Model.Model;
using FileSecretAssemblyStandard;
using Scripting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;


namespace ConfigInfoWebPlatform.API.BusinessCommon
{
    /// <summary>
    /// 通用解析路径中的配置文件信息
    /// </summary>
    public class ParseConfigFile
    {
        readonly DAL_ProgramNavicat programNavicat;
        readonly DAL_ConfigFile configFileDal;
        readonly string initDB = "";
        readonly InterfaceFileSecret FileSecret;
        public ParseConfigFile(DAL_ProgramNavicat _programNavicat, DAL_ConfigFile _configFileDal,string _initDB, InterfaceFileSecret fileSecret)
        {
            programNavicat = _programNavicat;
            initDB = _initDB;
            configFileDal = _configFileDal;
            FileSecret = fileSecret;
        }
        /// <summary>
        /// 解析流程配置目录到流程配置模型中
        /// </summary>
        /// <param name="dirPath">遍历的目录</param>
        /// <param name="rootPath">根目录</param>
        /// <param name="re">解析后的流程配置模型的列表</param>
        /// <param name="level">目录层级</param>
        /// <param name="parentId">父级ID</param>
        public void ParseCfgDirNew(string dirPath, string rootPath, string versionPath, List<ConfigFileInfoModel> re, int level, string parentId, string fname = "")
        {
            level += 1;
            var caseConfig = configFileDal.GetConfigFileByPath(dirPath.Replace("\\", @"/"));

            DirectoryInfo directory = new DirectoryInfo(Path.Combine(rootPath, versionPath, dirPath));

            DirectoryInfo[] childDir = directory.GetDirectories();

            if (!string.IsNullOrWhiteSpace(fname))
            {
                childDir = childDir.Where(x => x.Name.Contains(fname)).ToArray();
            }

            // 遍历当前目录下的子目录，经目录信息存入到配置文件的模型中
            foreach (DirectoryInfo directoryInfo in childDir)
            {
                var oldName = directoryInfo.FullName;
                var newName = directoryInfo.Name.ToLower();
                if (Regex.IsMatch(directoryInfo.Name,"[A-Z]"))
                {
                    FileSystemObject fso = new FileSystemObjectClass();
                    try
                    {
                        var nameTemp = $"{directoryInfo.Name.ToLower()}1";
                        var allNameTemp = $"{directoryInfo.Parent.FullName}\\{nameTemp}";
                        fso.GetFolder(oldName).Name= nameTemp;
                        fso.GetFolder(allNameTemp).Name = newName;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    
                }
                string currentId = System.Guid.NewGuid().ToString("N");
                ConfigFileInfoModel configFileInfo = new ConfigFileInfoModel();
                configFileInfo.currentId = currentId;
                configFileInfo.parentId = caseConfig.Currentid;
                configFileInfo.level = 3;
                configFileInfo.name = directoryInfo.Name.ToLower();
                configFileInfo.ctype = "D";
                configFileInfo.path = dirPath + "/" + directoryInfo.Name.ToLower();
                configFileInfo.parentPath = dirPath;
                configFileInfo.updateTime = directoryInfo.LastAccessTime.ToString("yyyy-MM-dd HH:mm:ss");
                configFileInfo.createdTime = directoryInfo.CreationTime.ToString("yyyy-MM-dd HH:mm:ss");
                re.Add(configFileInfo);
                AddConfigFileInfoToDB(configFileInfo, caseConfig.Programid.Value);
            }
        }
        /// <summary>
        /// 解析流程配置目录到流程配置模型中
        /// </summary>
        /// <param name="dirPath">遍历的目录</param>
        /// <param name="rootPath">根目录</param>
        /// <param name="re">解析后的流程配置模型的列表</param>
        /// <param name="level">目录层级</param>
        /// <param name="parentId">父级ID</param>
        public void ParseCfgFileNew(string dirPath, string rootPath, string versionPath, List<ConfigFileInfoModel> re, int level, string parentId, string start = "", string end = "", string fname = "", string fpath = "")
        {
            level += 1;

            var casePath = Path.GetDirectoryName(dirPath).Replace("\\", @"/");
            var caseConfig = configFileDal.GetConfigFileByPath(casePath);
            DirectoryInfo directory = new DirectoryInfo(Path.Combine(rootPath, versionPath, dirPath));
            FileInfo[] files = directory.GetFiles();
            // 遍历当前目录下的文件，将文件信息存入到配置文件模型中
            foreach (FileInfo file in files)
            {
                if (file.Extension == ".xml" || file.Extension == ".txt" || file.Extension == ".json")
                {
                    string currentId = System.Guid.NewGuid().ToString("N");
                    ConfigFileInfoModel configFileInfo = new ConfigFileInfoModel();
                    configFileInfo.programId = caseConfig.Programid.Value;
                    configFileInfo.currentId = currentId;
                    configFileInfo.parentId = caseConfig.Currentid;
                    configFileInfo.level = level;
                    configFileInfo.name = file.Name;
                    configFileInfo.ctype = "F";
                    //configFileInfo.path = file.FullName;
                    configFileInfo.path = dirPath + "/" + file.Name;
                    //configFileInfo.path = file.FullName.Replace("\\", "/").Replace(rootPath.Replace("\\", "/") + "/", "");
                    configFileInfo.parentPath = dirPath;
                    configFileInfo.fileSize = file.Length.ToString() + "B";
                    configFileInfo.updateTime = file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss");
                    configFileInfo.createdTime = file.CreationTime.ToString("yyyy-MM-dd HH:mm:ss");
                    string explain = "";
                    if (file.Extension == ".xml")
                    {
                        try
                        {
                            string filePath = directory + @"/" + file.Name;
                            FileInfo fileInfo = new FileInfo(filePath);
                            if (fileInfo.Length > 0)
                            {
                                string xmlContent = FileSecret.DecryptFileToContent(filePath);
                                var rootView = CommonHandle.DeserializeToObject<RootView>(xmlContent);
                                if (!string.IsNullOrWhiteSpace(rootView.Explain))
                                    explain = rootView.Explain;
                            }
                        }
                        catch (Exception ex)
                        {

                            explain = "";
                        }
                    }
                    configFileInfo.note = explain;
                    AddConfigFileInfoToDB(configFileInfo, caseConfig.Programid.Value);
                    re.Add(configFileInfo);
                }
            }
        }
        /// <summary>
        /// 解析流程配置目录到流程配置模型中
        /// </summary>
        /// <param name="dirPath">遍历的目录</param>
        /// <param name="rootPath">根目录</param>
        /// <param name="re">解析后的流程配置模型的列表</param>
        /// <param name="level">目录层级</param>
        /// <param name="parentId">父级ID</param>
        public void ParseCfgDir(string dirPath,string rootPath,string versionPath, List<ConfigFileInfoModel> re, int level, string parentId,string start="",string end="",string fname="",string fpath="")
        {
            level += 1;

            #region 获取功能ID
            List<ProgramNavicatModel> programNavicats = new List<ProgramNavicatModel>();
            programNavicats = programNavicat.GetProgramNavicatInfos();
            programNavicats = programNavicats.Where(a => a.Directory == dirPath).ToList();
            long programId = 0;
            if (programNavicats.Count > 0)
                programId = programNavicats.First().ID;
            #endregion

            DirectoryInfo directory = new DirectoryInfo(Path.Combine(rootPath, versionPath, dirPath));

            FileInfo[] files = directory.GetFiles();
            
            DirectoryInfo[] childDir = directory.GetDirectories();
            if (!string.IsNullOrWhiteSpace(start))
            {
                childDir = childDir.Where(x => x.LastWriteTime >= Convert.ToDateTime(start)).ToArray();
            }
            if (!string.IsNullOrWhiteSpace(end))
            {
                childDir = childDir.Where(x => x.LastWriteTime <= Convert.ToDateTime(end)).ToArray();
            }

            if (!string.IsNullOrWhiteSpace(fname))
            {
                childDir = childDir.Where(x => x.Name.Contains(fname)).ToArray();
            }

            if (!string.IsNullOrWhiteSpace(fpath))
            {
                childDir = childDir.Where(x => x.FullName.Replace(rootPath + "\\", "").Replace("\\", "/").Contains(fpath)).ToArray();
            }


            // 遍历当前目录下的文件，将文件信息存入到配置文件模型中
            foreach (FileInfo file in files)
            {
                if (file.Extension == ".xml" || file.Extension == ".txt" || file.Extension == ".json")
                {
                    string currentId = System.Guid.NewGuid().ToString("N");
                    ConfigFileInfoModel configFileInfo = new ConfigFileInfoModel();
                    configFileInfo.programId = programId;
                    configFileInfo.currentId = currentId;
                    configFileInfo.parentId = parentId;
                    configFileInfo.level = level;
                    configFileInfo.name = file.Name;
                    configFileInfo.ctype = "F";
                    //configFileInfo.path = file.FullName;
                    configFileInfo.path = dirPath + "/" + file.Name;
                    //configFileInfo.path = file.FullName.Replace("\\", "/").Replace(rootPath.Replace("\\", "/") + "/", "");
                    configFileInfo.parentPath = dirPath;
                    configFileInfo.fileSize = file.Length.ToString() + "B";
                    configFileInfo.updateTime = file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss");
                    configFileInfo.createdTime = file.CreationTime.ToString("yyyy-MM-dd HH:mm:ss");
                    string explain = "";
                    if (file.Extension == ".xml")
                    {
                        XmlDocument xmlDocument = new XmlDocument();
                        try
                        {
                            xmlDocument.Load(directory + @"\" + file.Name);
                            if (xmlDocument.SelectNodes("root").Count > 0 && xmlDocument.SelectNodes("root")[0].Attributes["explain"] != null)
                            {
                                explain = xmlDocument.SelectNodes("root")[0].Attributes["explain"].Value;
                            }
                        }
                        catch (Exception ex)
                        {
                            explain = "";
                        }
                    }
                    configFileInfo.note = explain;
                    AddConfigFileInfoToDB(configFileInfo, programId);
                    re.Add(configFileInfo);
                }
            }

            // 遍历当前目录下的子目录，经目录信息存入到配置文件的模型中
            foreach (DirectoryInfo directoryInfo in childDir)
            {
                string currentId = System.Guid.NewGuid().ToString("N");
                ConfigFileInfoModel configFileInfo = new ConfigFileInfoModel();
                configFileInfo.currentId = currentId;
                configFileInfo.parentId = parentId;
                configFileInfo.level = level;
                configFileInfo.name = directoryInfo.Name;
                configFileInfo.ctype = "D";
                //configFileInfo.path = directoryInfo.FullName.Replace("\\", "/").Replace(rootPath.Replace("\\", "/") + "/","");
                configFileInfo.path = dirPath + "/" + directoryInfo.Name;
                configFileInfo.parentPath = dirPath;
                configFileInfo.updateTime = directoryInfo.LastAccessTime.ToString("yyyy-MM-dd HH:mm:ss");
                configFileInfo.createdTime = directoryInfo.CreationTime.ToString("yyyy-MM-dd HH:mm:ss");
                re.Add(configFileInfo);
                AddConfigFileInfoToDB(configFileInfo, programId);
                this.ParseCfgDir(configFileInfo.path, rootPath, versionPath, re, level, currentId);
            }
        }

        /// <summary>
        /// 解析模块配置文件内容
        /// 这里的解析结果是一维的，主要为了方便前端页面能通过table来展示数据
        /// </summary>
        /// <param name="moduleConfig">模块配置文件XmlDocument</param>
        /// <param name="moduleName">模块名称</param>
        /// <param name="moduleConfigPath">模块配置文件目录</param>
        /// <returns></returns>
        public List<ModuleConfig> parseXmlMoudleConfig(XmlDocument moduleConfig, string moduleName, string moduleConfigPath)
        {
            List<ModuleConfig> moduleConfigs = new List<ModuleConfig>();
            // 获取step节点配置的结构化文件的目录
            FileInfo fileInfo = new FileInfo(moduleConfigPath);
            string dirp = fileInfo.Directory.FullName;

            XmlNodeList moduleNodelist = moduleConfig.SelectNodes("/root");
            XmlNode moduleRootNode = moduleNodelist[0];

            foreach (XmlNode stepNode in moduleRootNode.ChildNodes)
            {
                parseStepNode(stepNode, dirp, null, moduleConfigs);
            }
            return moduleConfigs;
        }

        /// <summary>
        /// 解析模块配置文件中配置的结构化xml文件
        /// </summary>
        /// <param name="stepNode">模块配置文件中的步骤节点</param>
        /// <param name="dirp">结构化xml文件所在的目录</param>
        /// <param name="parentNode">父节点</param>
        /// <param name="parsedConfigs">解析后的列表</param>
        public void parseStepNode(XmlNode stepNode, string dirp, ModuleConfig parentNode, List<ModuleConfig> parsedConfigs)
        {
            #region 根据节点属性解析到实体里面
            ModuleConfig configDetail = new ModuleConfig();
            if (stepNode.Attributes?["number"] == null)
            {
                configDetail.number = "";
            }
            else
            {
                configDetail.number = stepNode.Attributes["number"].Value;
            }
            if (stepNode.Attributes?["zh_cn"] == null)
            {
                configDetail.moduleName = "";
            }
            else
            {
                configDetail.moduleName = stepNode.Attributes["zh_cn"].Value;
            }
            if (stepNode.Attributes?["code"] == null)
            {
                configDetail.code = "";
            }
            else
            {
                configDetail.code = stepNode.Attributes["code"].Value;
            }
            if (stepNode.Attributes?["executetype"] == null)
            {
                configDetail.executeType = "";
            }
            else
            {
                configDetail.executeType = stepNode.Attributes["executetype"].Value;
            }
            if (stepNode.Attributes?["executecode"] == null)
            {
                configDetail.executeCode = "";
            }
            else
            {
                configDetail.executeCode = stepNode.Attributes["executecode"].Value;
            }
            if (stepNode.Attributes?["executefile"] == null)
            {
                configDetail.filePath = "";
            }
            else
            {
                configDetail.filePath = stepNode.Attributes["executefile"].Value;
            }

            if (parentNode == null)
            {
                parentNode = configDetail;
            }
            else
            {
                if (parentNode.configDetail == null)
                    parentNode.configDetail = new List<ModuleConfig>();
                parentNode.configDetail.Add(configDetail);
            }
            parsedConfigs.Add(configDetail);
            // 递归调用解析子节点
            foreach (XmlNode item in stepNode.ChildNodes)
            {
                // 这里的父节点传入的null就是为了让解析结果成一维的，方便前端页面能通过table来展示数据
                parseStepNode(item, dirp, null, parsedConfigs);
            }
            #endregion
        }

        /// <summary>
        /// 将配置文件信息添加到数据库中
        /// </summary>
        /// <param name="inputInfo">配置文件信息</param>
        /// <param name="programId">功能导航ID</param>
        public void AddConfigFileInfoToDB(ConfigFileInfoModel inputInfo, long programId)
        {
            // 如果配置初始化数据库，那么就将配置文件信息添加到数据库中
            if (initDB == "1")
            {
                if (configFileDal.ExistFile(inputInfo.path) <= 0)
                {
                    inputInfo.programId = programId;
                    configFileDal.AddConfigFile(inputInfo);
                }
            }
        }

        /// <summary>
        /// 保存全流程配置
        /// </summary>
        public void SaveWholeProcceeConfig()
        {
            bool isSave = false;
            do
            {

            } while (isSave);
        }

        /// <summary>
        /// 通过案件目录路径获取数据源配置信息
        /// </summary>
        /// <param name="caseDir"></param>
        /// <returns></returns>
        public List<ConfigFileInfoModel> GetDataSouresByCaseDir(string caseDir)
        {
            Expression<Func<ConfigFiles, bool>> where = null;
            where = where.And(x => x.ParentPath == caseDir && x.Ctype=="D");
            List<ConfigFileInfoModel> query = configFileDal.GetConfigFilesByFilter(where);
            return query;
        }

        /// <summary>
        /// 刷新统计数量
        /// </summary>
        public void RefreshStatistics() { 
            
        }
    }
}
